package jnpf.job;

import jnpf.base.UserInfo;
import jnpf.config.ConfigValueUtil;
import jnpf.util.data.DataSourceContextHolder;
import jnpf.engine.entity.FlowTaskOperatorEntity;
import jnpf.engine.model.flowmessage.FlowMsgModel;
import jnpf.engine.model.flowtask.WorkJobModel;
import jnpf.engine.util.FlowMsgUtil;
import jnpf.util.RedisUtil;
import jnpf.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.quartz.QuartzJobBean;

import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 流程设计
 *
 * @author JNPF开发平台组
 * @version V3.3.0 flowable
 * @copyright 引迈信息技术有限公司
 * @date 2022/6/1 17:32
 */
@Slf4j
public class WorkJobNew extends QuartzJobBean {

    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private ConfigValueUtil configValueUtil;
    @Autowired
    private FlowMsgUtil flowMsgUtil;
    @Autowired
    private RedisTemplate redisTemplate;



    @Override
    protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
        List<WorkJobModel> listRedis = WorkJobUtil.getListRedis(redisUtil);
        if (CollectionUtils.isNotEmpty(listRedis)) {
            try {
                long time = System.currentTimeMillis();
                for (WorkJobModel workJobModel : listRedis) {
                    boolean useSuccess = redisTemplate.opsForValue().setIfAbsent(WorkJobUtil.REDIS_KEY+"_key:"+workJobModel.getTaskId(), System.currentTimeMillis(), 300, TimeUnit.SECONDS);
                    if(!useSuccess)continue;
                    List<FlowTaskOperatorEntity> operatorList = workJobModel.getFlowMsgModel().getOperatorList();
                    boolean isNext = operatorList.stream().filter(t -> t.getCreatorTime().getTime() > time).count() == 0;
                    UserInfo userInfo = workJobModel.getUserInfo();
                    FlowMsgModel flowMsgModel = workJobModel.getFlowMsgModel();
                    if (configValueUtil.isMultiTenancy()) {
                        if (StringUtil.isNotEmpty(userInfo.getTenantDbConnectionString())) {
                            DataSourceContextHolder.setDatasource(userInfo.getTenantId(), userInfo.getTenantDbConnectionString());
                        }
                    }
                    if (isNext) {
                        flowMsgUtil.message(flowMsgModel);
                        redisUtil.removeHash(WorkJobUtil.REDIS_KEY, workJobModel.getTaskId());
                        redisUtil.remove(WorkJobUtil.REDIS_KEY+"_key:"+workJobModel.getTaskId());
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
                log.error("工作流调度报错:" + e.getMessage());
            }
        }
    }
}
